import 'dart:async';

import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/services.dart';
import 'package:polyv_video_plugin/polyv_utils.dart';

typedef void PolyvVideoPlayerCreatedCallback(PolyvController controller);

class PolyvController {
  MethodChannel _channel;

  ///定义一个Controller
  StreamController<Map> _dataController = StreamController<Map>();
  ///获取 StreamSink 做 add 入口
  StreamSink<Map> get _dataSink => _dataController.sink;
  ///获取 Stream 用于监听
  Stream<Map> get _dataStream => _dataController.stream;
  ///事件订阅对象
  StreamSubscription _dataSubscription;

  PolyvController.init(int id) {
    _channel = new MethodChannel('polyv_video_plugin_$id');
    _channel.setMethodCallHandler(_platformCallHandler);
  }

  PolyvController.destroy(int id) {
    _dataSubscription.cancel();
    _dataController.close();
    _channel.invokeMethod('destory');
  }

  Future<dynamic> _platformCallHandler(MethodCall call) async {
    _dataSink.add(call.arguments);
  }

  Future<dynamic> listen(callback(Map arg)) async {
    _dataSubscription = _dataStream.listen((value){
      ///do change
      callback(value);
    });
  }

  Future<void> setVideoURI(String url) async {
    assert(url != null);
    return _channel.invokeMethod('setVideoURI', {"url":url});
  }

  Future<void> setVid(String vid) async {
    assert(vid != null);
    return _channel.invokeMethod('setVid', {"vid":vid});
  }

  Future<void> initPlayer() async {
    return _channel.invokeMethod('init');
  }

  Future<void> start() async {
    return _channel.invokeMethod('start');
  }

  Future<void> pause() async {
    return _channel.invokeMethod('pause');
  }

  Future<void> resume() async {
    return _channel.invokeMethod('resume');
  }

  Future<void> stop() async {
    return _channel.invokeMethod('stop');
  }

  Future<bool> isPlaying() {
    return _channel.invokeMethod('isPlaying');
  }

  Future<void> destroy() {
    return _channel.invokeMethod('destroy');
  }

  Future<int> getDuration() {
    return _channel.invokeMethod('duration');
  }

  Future<int> getCurrentPosition() {
    return _channel.invokeMethod('currentPosition');
  }

  Future<int> getBufferPercentage() {
    return _channel.invokeMethod('bufferPercentage');
  }

  Future<int> getBrightness() {
    return _channel.invokeMethod('brightness');
  }

  Future<int> getVolume() {
    return _channel.invokeMethod('volume');
  }

  Future<void> setBrightness(int brightness) {
    return _channel
        .invokeMethod('setBrightness', {"brightness": brightness.toString()});
  }

  Future<void> setVolume(int volume) {
    return _channel.invokeMethod('setVolume', {"volume": volume.toString()});
  }

  Future<void> seekTo(int progress) {
    return _channel.invokeMethod('seekTo', {"progress": progress.toString()});
  }

  // 获取播放速度
  Future<double> playRate() {
    return _channel.invokeMethod('playRate');
  }

  // 设置播放速度
  Future<void> setPlayRate(double rate) {
    return _channel.invokeMethod('setPlayRate', {"rate": rate.toString()});
  }
  
  // 获取可用清晰度数量
  Future<int> qualityCount() {
    return _channel.invokeMethod('qualityCount');
  }
  
  // 获取视频默认清晰度
  Future<double> preferredQuality(int progress) {
    return _channel.invokeMethod('preferredQuality');
  }
  
  // 获取当前清晰度
  Future<double> currentQuality() {
    return _channel.invokeMethod('currentQuality');
  }

  // 设置清晰度
  Future<void> setQuality(double quality) {
    return _channel.invokeMethod('setQuality', {"quality": quality.toString()});
  }
}

class PolyvPlayer extends StatefulWidget {
  final PolyvVideoPlayerCreatedCallback onCreated;
  final Set<Factory<OneSequenceGestureRecognizer>> gestureRecognizers;

  PolyvPlayer({
    Key key,
    @required this.onCreated,
    this.gestureRecognizers,
  });

  @override
  State<StatefulWidget> createState() => _VideoPlayerState();
}

class _VideoPlayerState extends State<PolyvPlayer> {
  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return defaultTargetPlatform == TargetPlatform.android
        ? AndroidView(
            viewType: 'plugins.polyv/video',
            onPlatformViewCreated: onPlatformViewCreated,
            creationParamsCodec: const StandardMessageCodec(),
          )
        : UiKitView(
            viewType: 'plugins.polyv/video',
            onPlatformViewCreated: onPlatformViewCreated,
            creationParamsCodec: const StandardMessageCodec(),
          );
  }

  Future<void> onPlatformViewCreated(id) async {
    if (widget.onCreated == null) {
      return;
    }
    widget.onCreated(new PolyvController.init(id));
  }
}
